<template>
  <div class="chat-container">
    <el-row>
      <!-- 在线用户列表 -->
      <el-col :span="4">
        <el-card class="user-list-card">
          <div class="user-list-header">
            在线用户
            <span class="user-list-subtext">（点击开始聊天）</span>
          </div>
          <div
            v-for="user in users"
            :key="user.username"
            class="user-list-item"
            @click="selectChatUser(user.username)"
            :class="{ selected: user.username === chatUser }"
          >
            <span>{{ user.username }}</span>
            <span v-if="user.username === chatUser" class="chatting-indicator">chatting...</span>
          </div>
        </el-card>
      </el-col>

      <!-- 聊天窗口 -->
      <el-col :span="20">
        <div class="chat-box">
          <div class="chat-header">{{ chatHeader }}</div>
          <div class="chat-content">
            <div v-if="chatUser">
              <div
                v-for="(msg, index) in currentChatMessages"
                :key="index"
                :class="msg.user === user.username ? 'self-message' : 'other-message'"
              >
                <div class="message-bubble">
                  <span>{{ msg.text }}</span>
                  <div class="message-timestamp">{{ formatTimestamp(msg.timestamp) }}</div>
                </div>
              </div>
            </div>
            <div v-else>
              <p>请先选择一个好友进行聊天。</p>
            </div>
          </div>

          <div class="chat-input-box" v-if="chatUser">
            <textarea v-model="text" class="chat-input"></textarea>
            <el-button type="primary" size="small" @click="send">发送</el-button>
          </div>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
export default {
  name: "Im",
  data() {
    return {
      user: {},
      users: [],
      chatUser: '',
      text: "",
      messages: {},
      socket: null
    };
  },
  computed: {
    currentChatMessages() {
      return this.messages[this.chatUser] || [];
    },
    chatHeader() {
      return `Web聊天室（${this.chatUser || '请选择聊天对象'}）`;
    }
  },
  created() {
    this.initializeWebSocket();
  },
  beforeRouteLeave(to, from, next) {
    if (this.socket) {
      this.socket.close();
    }
    next();
  },
  methods: {
    formatTimestamp(timestamp) {
      if (!timestamp) return '';
      const date = new Date(timestamp);
      return date.toLocaleString();
    },
    selectChatUser(username) {
      if (this.chatUser !== username) {
        this.chatUser = username;
      }
    },
    send() {
      if (!this.chatUser || !this.text.trim()) {
        this.$message({
          type: 'warning',
          message: !this.chatUser ? "请选择聊天对象" : "请输入内容"
        });
        return;
      }

      if (this.socket.readyState !== WebSocket.OPEN) {
        this.$message({
          type: 'error',
          message: 'WebSocket未连接，无法发送消息'
        });
        return;
      }

      const message = { from: this.user.username, to: this.chatUser, text: this.text };
      this.socket.send(JSON.stringify(message));
      this.addMessageToChat(this.user.username, this.text, this.chatUser);
      this.text = '';
    },
    addMessageToChat(sender, text, chatUser) {
      if (!this.messages[chatUser]) {
        this.messages[chatUser] = []; // 直接赋值，无需使用 this.$set
      }
      this.messages[chatUser].push({ user: sender, text, timestamp: new Date() });
    },
    initializeWebSocket() {
      this.user = JSON.parse(sessionStorage.getItem("user")) || {};
      const username = this.user.username;
      const socketUrl = `ws://localhost:9090/imserver/${username}`;

      if (this.socket) {
        this.socket.close();
      }

      this.socket = new WebSocket(socketUrl);

      this.socket.onopen = () => console.log("WebSocket已连接");
      this.socket.onmessage = (msg) => this.handleIncomingMessage(msg);
      this.socket.onclose = () => console.log("WebSocket已关闭");
      this.socket.onerror = () => console.error("WebSocket发生错误");
    },
    handleIncomingMessage(msg) {
      const data = JSON.parse(msg.data);

      if (data.users) {
        this.users = data.users.filter(user => user.username !== this.user.username);

        if (!this.users.some(user => user.username === this.chatUser)) {
          this.chatUser = '';
          this.$message({
            type: 'info',
            message: '聊天对象已离线，请选择其他用户'
          });
        }
      } else {
        const chatPartner = data.from === this.user.username ? data.to : data.from;

        if (!this.messages[chatPartner]) {
          this.messages[chatPartner] = []; // 直接赋值，无需使用 this.$set
        }

        this.messages[chatPartner].push({
          user: data.from,
          text: data.text,
          timestamp: data.timestamp || new Date()
        });
      }
    }
  }
};
</script>

<style scoped>
.chat-container {
  padding: 10px;
  margin-bottom: 50px;
}

.user-list-card {
  width: 100%;
  height: 100%;
  color: #333;
}

.user-list-header {
  padding-bottom: 10px;
  border-bottom: 1px solid #ccc;
}

.user-list-subtext {
  font-size: 12px;
}

.user-list-item {
  padding: 10px 0;
  cursor: pointer;
}

.user-list-item.selected {
  background-color: #f0f0f0;
}

.user-list-item:hover {
  background-color: #e0e0e0;
}

.chatting-indicator {
  font-size: 12px;
  color: limegreen;
  margin-left: 5px;
}

.chat-box {
  width: 100%;
  margin: 0 auto;
  background-color: white;
  border-radius: 5px;
  box-shadow: 0 0 10px #ccc;
}

.chat-header {
  text-align: center;
  line-height: 50px;
}

.chat-content {
  height: 350px;
  overflow: auto;
  padding: 10px;
  border-top: 1px solid #ccc;
}

.chat-input-box {
  display: flex;
  flex-direction: column;
  height: 200px;
}

.chat-input {
  height: 160px;
  width: 100%;
  padding: 20px;
  border: none;
  border-top: 1px solid #ccc;
  border-bottom: 1px solid #ccc;
  outline: none;
}

.self-message,
.other-message {
  display: flex;
  align-items: flex-start;
  margin-bottom: 10px;
}

.self-message {
  justify-content: flex-end;
}

.self-message .message-bubble {
  background-color: greenyellow;
  color: black;
  border-radius: 10px;
  padding: 10px;
  max-width: 60%;
}

.other-message {
  justify-content: flex-start;
}

.other-message .message-bubble {
  background-color: deepskyblue;
  color: white;
  border-radius: 10px;
  padding: 10px;
  max-width: 60%;
}

.message-bubble {
  display: inline-block;
  position: relative;
  word-wrap: break-word;
}

.self-message .message-bubble::after {
  content: '';
  position: absolute;
  right: -10px;
  top: 10px;
  border-width: 10px;
  border-style: solid;
  border-color: forestgreen transparent transparent transparent;
}

.other-message .message-bubble::after {
  content: '';
  position: absolute;
  left: -10px;
  top: 10px;
  border-width: 10px;
  border-style: solid;
  border-color: deepskyblue transparent transparent transparent;
}

.message-timestamp {
  font-size: 10px;
  color: black;
  text-align: right;
  margin-top: 5px;
}
</style>
